/**
 * 拖动插件
 * @module drag
 * @requires ui
 */
define("drag", ["ui"], function(ui, Lyx){
	/** 
	 * @constructor
	 * @alias module:drag
	 * @param {element} el 目标元素
	 * @param {object} [on] 事件合集
	 * @param {onMouse} [on.down] 按下事件
	 * @param {onMouse} [on.move] 移动事件
	 * @param {onMouse} [on.up] 抬起事件
	 * @param {object} [config] 运行上下文
	 * @param {object} [config.mappingEl] 映射元素，对目标元素的移动将会映射到该元素
	 * @param {object} [config.closeTarget] 当存在映射元素时，是否还移动目标元素
	 * @param {object} [context.context] 运行上下文
	 */
	return Lyx.createClass(function(p2t){
		var onDown = function()
		{
			// 存在映射元素时
			if (this.config.mappingEl) {
				this.mappingTop = parseFloat(this.mappingStyle.top);
				this.mappingLeft = parseFloat(this.mappingStyle.left);
				this.mappingTop = isNaN(this.mappingTop) ? 0 : this.mappingTop;
				this.mappingLeft = isNaN(this.mappingLeft) ? 0 : this.mappingLeft;
			}
			this.top = parseFloat(this.style.top);
			this.left = parseFloat(this.style.left);
			this.top = isNaN(this.top) ? 0 : this.top;
			this.left = isNaN(this.left) ? 0 : this.left;
			if(Lyx.isFunction(this.on.down))
			{
				this.on.down.call(this.context, this);
			}
		};

		var onMove = function()
		{
			if (this.config.mappingEl) {
				this.mappingStyle.top = this.mappingTop + this.offsetY;
				this.mappingStyle.left = this.mappingLeft + this.offsetX;
			}
			if (!this.config.closeTarget) {
				this.style.top = this.top + this.offsetY;
				this.style.left = this.left + this.offsetX;
			}
			if(Lyx.isFunction(this.on.move))
			{
				this.on.move.call(this.context, this);
			}
		};

		var onUp = function()
		{
			if(Lyx.isFunction(this.on.up))
			{
				this.on.up.call(this.context, this);
			}
		};
		
		p2t.init = function(el, on, config)
		{
			this.switch = true;
			this.$switch = {
				set: function(value, oldValue)
				{
					if(value != oldValue)
					{
						ui.hander[value ? "add" : "remove"](this.el, "mousedown", this.down);
					}
				}
			};
			Lyx.observe(this);
			this.on = on || {};
			this.config = config || {};
			this.context = this.config.context || this;
			if(Lyx.type(el) === "string")
			{
				el = ui.$(el);
			}
			if (Lyx.type(this.config.mappingEl) == "string") {
				this.config.mappingEl = ui.$(this.config.mappingEl);
			}
			
			this.el = el;

			this.inner = {};

			/**
			 * 鼠标按下时的x轴位置
			 * @member {number}
			 */
			this.x = 0;

			/**
			 * 鼠标按下时y轴位置
			 * @member {number}
			 */
			this.y = 0;

			/**
			 * 在一次拖动过程中，鼠标相对于起始位置x轴方向的偏移
			 * @member {number}
			 */
			this.offsetX = 0;

			/**
			 * 在一次拖动过程中，鼠标相对于起始位置y轴方向的偏移
			 * @member {number}
			 */
			this.offsetY = 0;

			/**
			 * 代理目标元素的style属性
			 * @member {object}
			 */
			this.style = ui.getStyle(this.el);

			if (this.config.mappingEl) {
				this.mappingStyle = ui.getStyle(this.config.mappingEl);
				position = this.mappingStyle.position;
				if(position === "static" || position == "inherit")
				{
					this.mappingStyle.position = "relative";
				}
			}

			// 设置定位属性，如果未设置则默认为relative
			var position = this.style.position;
			if(position === "static" || position == "inherit")
			{
				this.style.position = "relative";
			}

			// 绑定函数的this指向
			this.down = this.down.bind(this);
			this.move = this.move.bind(this);
			this.up = this.up.bind(this);

			ui.hander.add(this.el, "mousedown", this.down);
		};

		p2t.down = function(event)
		{
			if(event.button == 0)
			{
				this.x = event.clientX;
				this.y = event.clientY;
				ui.hander.add(document, "mousemove", this.move);
				ui.hander.add(document, "mouseup", this.up);
				onDown.call(this);
			}
			ui.stop(event);
		};

		p2t.move = function(event)
		{
			this.offsetX = event.clientX - this.x;
			this.offsetY = event.clientY - this.y;
			onMove.call(this);
			ui.stop(event);
		};

		p2t.up = function(event)
		{
			this.offsetX = 0;
			this.offsetY = 0;
			ui.hander.remove(document, "mousemove", this.move);
			ui.hander.remove(document, "mouseup", this.up);
			onUp.call(this);
			ui.stop(event);
		}
	});
});